home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / ODF / OS / FWToolbx / Sources / PRAlert.cpp < prev    next >
Encoding:
Text File  |  1996-08-16  |  10.5 KB  |  448 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                PRAlert.cpp
  4. //    Release Version:    $ ODF 1 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWOS.hpp"
  11.  
  12. #ifndef FWODTYPS_H
  13. #include "FWODTyps.h"
  14. #endif
  15.  
  16. #ifndef PRALERT_H
  17. #include "PRAlert.h"
  18. #endif
  19.  
  20. #ifndef FWRESOUR_H
  21. #include "FWResour.h"
  22. #endif
  23.  
  24. #ifndef FWSTRING_H
  25. #include "FWString.h"
  26. #endif
  27.  
  28. #ifndef SOM_Module_OpenDoc_Errors_defined
  29. #include <ErrorDef.xh>
  30. #endif
  31.  
  32. // ----- Macintosh Includes -----
  33.  
  34. #if defined(FW_BUILD_MAC) && !defined(__TEXTUTILS__)
  35. #include <TextUtils.h>
  36. #endif
  37.  
  38. #if defined(FW_BUILD_MAC) && !defined(__ICONS__)
  39. #include <Icons.h>
  40. #endif
  41.  
  42. #if defined(FW_BUILD_MAC) && !defined(__DIALOGS__)
  43. #include <Dialogs.h>
  44. #endif
  45.  
  46. //========================================================================================
  47. //    Runtime Informations
  48. //========================================================================================
  49.  
  50. #ifdef FW_BUILD_MAC    
  51. #pragma segment fwtoolbx
  52. #endif
  53.  
  54. //========================================================================================
  55. // Macintosh Dialog Refcon structure
  56. //========================================================================================
  57.  
  58. #ifdef FW_BUILD_MAC
  59. struct FW_SMacAlertRefCon
  60. {
  61.     short fOkItemId;
  62.     short fCancelItemId;
  63. };
  64. #endif
  65.  
  66. #ifdef FW_BUILD_MAC    
  67. //========================================================================================
  68. //    MacAlertDialogFilter
  69. //========================================================================================
  70.  
  71. static pascal Boolean MacAlertDialogFilter(DialogPtr theDialog, 
  72.                                             EventRecord * theEvent, 
  73.                                             short *itemHit)
  74. {
  75.     Boolean result = FALSE;
  76.  
  77.     FW_SMacAlertRefCon* alertRefCon = (FW_SMacAlertRefCon*)::GetWRefCon(theDialog);
  78.     
  79.     switch (theEvent->what)
  80.     {
  81.         case keyDown:
  82.         case autoKey:
  83.             {
  84.                 switch (theEvent->message & charCodeMask)
  85.                 {
  86.                     case '.':
  87.                         if (theEvent->modifiers & cmdKey && alertRefCon->fCancelItemId != 0)
  88.                         {
  89.                             result = TRUE;
  90.                             *itemHit = alertRefCon->fCancelItemId;
  91.                         }
  92.                         break;
  93.                     
  94.                     case 0x0D:
  95.                     case 0x03:
  96.                         result = TRUE;
  97.                         *itemHit = alertRefCon->fOkItemId;
  98.                         break;
  99.                     
  100.                     case 0x1B:
  101.                         if (alertRefCon->fCancelItemId != 0)
  102.                         {
  103.                             result = TRUE;
  104.                             *itemHit = alertRefCon->fCancelItemId;
  105.                         }
  106.                         break;                
  107.                 }
  108.                 
  109.                 if (result)        // flash the button
  110.                 {
  111.                     long     theTick;
  112.                     short     itemType;
  113.                     Handle     hItem;
  114.                     Rect    box;
  115.                     
  116.                     ::GetDialogItem(theDialog, *itemHit, &itemType, &hItem, &box);
  117.                     ::HiliteControl((ControlHandle)hItem, 1);
  118.                     ::Delay(6,&theTick);
  119.                     ::HiliteControl((ControlHandle)hItem, 0);            
  120.                 }
  121.             }
  122.             break;
  123.         
  124.         case updateEvt:
  125.             if (theDialog == (DialogPtr)theEvent->message)
  126.             {
  127.                 PenState     ps;
  128.                 Rect        box;
  129.                 Handle        handle;
  130.                 short        type;
  131.                 
  132.                 ::SetPort(theDialog);
  133.                 ::GetPenState(&ps);
  134.                 ::PenSize(3, 3);
  135.                 ::GetDialogItem(theDialog, alertRefCon->fOkItemId, &type, &handle, &box);
  136.                 ::InsetRect(&box, -4, -4);
  137.                 ::FrameRoundRect(&box, 16, 16);
  138.                 ::SetPenState(&ps);
  139.             }
  140.             break;
  141.     }
  142.  
  143.     return result;
  144. }
  145. #endif
  146.  
  147. #ifdef FW_BUILD_MAC
  148. //----------------------------------------------------------------------------------------
  149. //    MacSetButtonText
  150. //----------------------------------------------------------------------------------------
  151.  
  152. static void MacSetButtonText(DialogPtr dialog, short buttonId, Str32 text, FW_Boolean moveButton)
  153. {
  154.     Rect             rect;
  155.     short             type;
  156.     Handle             handle;
  157.  
  158.     ::GetDialogItem(dialog, buttonId, &type, &handle, &rect);
  159.     if (text[0] != 0)
  160.     {
  161.         ::SetControlTitle(ControlHandle(handle), text);
  162.         if (moveButton)
  163.         {
  164.             ::OffsetRect(&rect, 10, 0);
  165.             ::SetDialogItem(dialog, buttonId, type, handle, &rect);
  166.             ::MoveControl(ControlHandle(handle), rect.left, rect.top);
  167.         }
  168.     }
  169.     else
  170.     {
  171.         ::HideControl(ControlHandle(handle));
  172.     }
  173. }
  174. #endif
  175.  
  176. //----------------------------------------------------------------------------------------
  177. //    FW_PrivAlert
  178. //----------------------------------------------------------------------------------------
  179. FW_AlertResult SL_API FW_PrivAlert(Environment* ev,
  180.                             FW_HString captionRep,
  181.                             FW_HString messageRep,
  182.                             FW_ButtonType buttonType,
  183.                             FW_IconType iconType,
  184.                             FW_DefaultButton defaultButton,
  185.                             FW_Boolean beep)
  186. {
  187.     FW_CString caption(captionRep);
  188.     FW_CString message(messageRep);
  189.  
  190. #ifdef FW_BUILD_WIN
  191.     UINT dialogFlags = buttonType | iconType | defaultButton | MB_TASKMODAL;
  192.     dialogFlags ^= dialogFlags & MB_SYSTEMMODAL;
  193.     
  194.     // ::MessageBox() doesn't work if mouse capturing is active,
  195.     //  so we release the capture (if any) and then restore it
  196.  
  197.     const HWND hwndCapture = ::GetCapture();
  198.  
  199.     if (hwndCapture != NULL)
  200.         ::ReleaseCapture();
  201.     
  202.     if (beep)
  203.         ::MessageBeep((UINT)iconType);
  204.     
  205.     FW_CAcquireNulTerminatedString255 szMessage(message);
  206.     FW_CAcquireNulTerminatedString255 szCaption(caption);
  207.  
  208.     short result = ::MessageBox(NULL, szMessage, szCaption, dialogFlags);
  209.  
  210.     // Set mouse capture to the window that had it
  211.     if (hwndCapture != 0)
  212.         ::SetCapture(hwndCapture);
  213.  
  214.     return result;
  215. #endif
  216.  
  217. #ifdef FW_BUILD_MAC
  218. #define kDialogID 500
  219. // ----- dialog item ids
  220. #define kButton1Id     1
  221. #define kButton2Id    2
  222. #define kButton3Id     3
  223. #define    kMessageId    4
  224. #define    kIconId        5
  225.  
  226.     GrafPtr curPort;
  227.     ::GetPort(&curPort);
  228.     
  229.     DialogPtr dlg = NULL;
  230.     FW_VOLATILE(dlg);
  231.     
  232.     short items[3];
  233.     short item;
  234.  
  235.     FW_TRY 
  236.     {
  237.         // ----- Open create the dialog (can't do exception here because used to display exception messages)
  238.         {
  239.             FW_CAcquireCFMResourceAccess a(ev);
  240.             dlg = ::GetNewDialog(kDialogID, NULL, WindowPtr(-1));
  241.         }
  242.         
  243.         FW_SMacAlertRefCon    alertRefCon;
  244.         ::SetWRefCon(dlg, (long)&alertRefCon);
  245.         
  246.         Rect             rect;
  247.         short             type;
  248.         Handle             handle;
  249.         
  250.         ::GetDialogItem(dlg, kMessageId, &type, &handle, &rect);
  251.         
  252.         Str255 str;
  253.         message.ExportPascal(str);
  254.         ::SetDialogItemText(handle, str);
  255.     
  256.         Str32 but1, but2, but3;
  257.         but1[0] = 0;
  258.         but2[0] = 0;
  259.         but3[0] = 0;
  260.     
  261.         FW_Boolean moveButton = FALSE;
  262.         
  263.         switch (buttonType)
  264.         {
  265.             case FW_kOK:
  266.                 {
  267.                     FW_CAcquireCFMResourceAccess a(ev);
  268.                     ::GetIndString(but1, kDialogID, 1);        // OK
  269.                     alertRefCon.fOkItemId = 1;
  270.                     alertRefCon.fCancelItemId = 0;
  271.                     items[0] = FW_kOKButtonPressed;
  272.                     break;
  273.                 }
  274.             case FW_kOKCancel:
  275.                 {
  276.                     FW_CAcquireCFMResourceAccess a(ev);
  277.                     ::GetIndString(but1, kDialogID, 1);        // OK
  278.                     ::GetIndString(but2, kDialogID, 2);        // Cancel
  279.                     if (defaultButton == FW_kDefaultButton2)
  280.                     {
  281.                         alertRefCon.fCancelItemId = 0;
  282.                         alertRefCon.fOkItemId = 2;
  283.                     }
  284.                     else
  285.                     {
  286.                         alertRefCon.fOkItemId = 1;
  287.                         alertRefCon.fCancelItemId = 2;
  288.                     }
  289.                     items[0] = FW_kOKButtonPressed;
  290.                     items[1] = FW_kCancelButtonPressed;
  291.                     break;
  292.                 }
  293.             case FW_kAbortRetryIgnore:
  294.                 {
  295.                     FW_CAcquireCFMResourceAccess a(ev);
  296.                     ::GetIndString(but1, kDialogID, 3);        // Abort
  297.                     ::GetIndString(but2, kDialogID, 4);        // Retry
  298.                     ::GetIndString(but3, kDialogID, 5);        // Ignore
  299.                     alertRefCon.fOkItemId = defaultButton + 1;
  300.                     alertRefCon.fCancelItemId = 0;
  301.                     items[0] = FW_kAbortButtonPressed;
  302.                     items[1] = FW_kRetryButtonPressed;
  303.                     items[2] = FW_kIgnoreButtonPressed;
  304.                     break;
  305.                 }
  306.             case FW_kYesNoCancel:
  307.                 {
  308.                     FW_CAcquireCFMResourceAccess a(ev);
  309.                     ::GetIndString(but1, kDialogID, 6);        // Yes
  310.                     ::GetIndString(but2, kDialogID, 7);        // No
  311.                     ::GetIndString(but3, kDialogID, 2);        // Cancel
  312.                     if (defaultButton == FW_kDefaultButton1)
  313.                     {
  314.                         alertRefCon.fOkItemId = 1;
  315.                         alertRefCon.fCancelItemId = 3;
  316.                     }
  317.                     else if (defaultButton == FW_kDefaultButton2)
  318.                     {
  319.                         alertRefCon.fOkItemId = 2;
  320.                         alertRefCon.fCancelItemId = 3;
  321.                     }
  322.                     else
  323.                     {
  324.                         // I can't decide if Esc means Yes or No
  325.                         alertRefCon.fOkItemId = 3;
  326.                         alertRefCon.fCancelItemId = 0;
  327.                     }
  328.                     items[0] = FW_kYesButtonPressed;
  329.                     items[1] = FW_kNoButtonPressed;
  330.                     items[2] = FW_kCancelButtonPressed;
  331.                     moveButton = TRUE;
  332.                     break;
  333.                 }
  334.             case FW_kYesNo:
  335.                 {
  336.                     FW_CAcquireCFMResourceAccess a(ev);
  337.                     ::GetIndString(but1, kDialogID, 6);        // Yes
  338.                     ::GetIndString(but2, kDialogID, 7);        // No
  339.                     alertRefCon.fCancelItemId = 0;
  340.                     if (defaultButton == FW_kDefaultButton2)
  341.                         alertRefCon.fOkItemId = 2;
  342.                     else
  343.                         alertRefCon.fOkItemId = 1;
  344.                     items[0] = FW_kYesButtonPressed;
  345.                     items[1] = FW_kNoButtonPressed;
  346.                     break;
  347.                 }
  348.             case FW_kRetryCancel:
  349.                 {
  350.                     FW_CAcquireCFMResourceAccess a(ev);
  351.                     ::GetIndString(but1, kDialogID, 4);        // Retry
  352.                     ::GetIndString(but2, kDialogID, 2);        // Cancel
  353.                     if (defaultButton == FW_kDefaultButton2)
  354.                     {
  355.                         alertRefCon.fCancelItemId = 0;
  356.                         alertRefCon.fOkItemId = 2;
  357.                     }
  358.                     else
  359.                     {
  360.                         alertRefCon.fOkItemId = 1;
  361.                         alertRefCon.fCancelItemId = 2;
  362.                     }
  363.                     items[0] = FW_kRetryButtonPressed;
  364.                     items[1] = FW_kCancelButtonPressed;
  365.                     break;
  366.                 }
  367.             default:
  368.                 FW_ASSERT(0);                            // unknown dialogFlags
  369.                 break;
  370.         }
  371.     
  372.         MacSetButtonText(dlg, kButton1Id, but1, FALSE);
  373.         MacSetButtonText(dlg, kButton2Id, but2, moveButton);
  374.         MacSetButtonText(dlg, kButton3Id, but3, FALSE);
  375.             
  376.         // ----- Icons
  377.         Handle hIcon = NULL;
  378.         switch (iconType)
  379.         {
  380.             case FW_kStopAlert:
  381.                 hIcon = ::GetIcon(stopIcon);
  382.                 break;
  383.             
  384.             case FW_kCautionAlert:
  385.                 hIcon = ::GetIcon(cautionIcon);
  386.                 break;
  387.             
  388.             case FW_kNoteAlert:
  389.                 hIcon = ::GetIcon(noteIcon);
  390.                 break;
  391.         };
  392.         
  393.         ::GetDialogItem(dlg, kIconId, &type, &handle, &rect);
  394.         if (hIcon)
  395.         {
  396.             ::SetDialogItem(dlg, kIconId, type, hIcon, &rect);
  397.         }
  398.         else
  399.         {
  400.             ::GetDialogItem(dlg, kIconId, &type, &handle, &rect);
  401.             short left = rect.left;
  402.             ::OffsetRect(&rect, 1000, 0);
  403.             ::SetDialogItem(dlg, kIconId, type, hIcon, &rect);
  404.             
  405.             ::GetDialogItem(dlg, kMessageId, &type, &handle, &rect);
  406.             rect.left = left;
  407.             ::SetDialogItem(dlg, kMessageId, type, handle, &rect);        
  408.         }
  409.             
  410.         if (beep)
  411.             ::SysBeep(16);
  412.     
  413.         ::ShowWindow(dlg);
  414.         
  415.         ModalFilterUPP filterProc = NewModalFilterProc(&MacAlertDialogFilter);
  416.         do
  417.         {
  418.             ::ModalDialog(filterProc, &item);
  419.         } while (item <kButton1Id || item > kButton3Id);
  420.         
  421.         DisposeRoutineDescriptor(filterProc);
  422.         
  423.     }
  424.     FW_CATCH_BEGIN 
  425.     FW_CATCH_REFERENCE(FW_XException, exception)
  426.     {
  427.         if (dlg)
  428.             ::DisposeDialog(dlg);
  429.         ::SetPort(curPort);
  430.         FW_SetException(ev, exception);
  431.     }
  432.     FW_CATCH_EVERYTHING () 
  433.     {
  434.         if (dlg)
  435.             ::DisposeDialog(dlg);
  436.         ::SetPort(curPort);
  437.         FW_SetEvError(ev, kODErrUndefined);
  438.     }
  439.     FW_CATCH_END
  440.  
  441.     ::DisposeDialog(dlg);
  442.     
  443.     ::SetPort(curPort);
  444.     
  445.     return (items[item - 1]);
  446. #endif
  447. }
  448.